package com.adingxiong.cft.util;

import com.adingxiong.cft.common.FileData;
import com.adingxiong.cft.errors.ApiException;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @ClassName AutoMergeExcel
 * @Description TODO
 * @Author xiongchao
 * @Date 2021/6/9 17:12
 **/
@Slf4j
public class AutoMergeExcel {

    /**
     *  场景 :
     *   Excel 表头跨行跨列合并
     * @param map
     * @return
     */
    private Map<String,List<String>> getHeader(Map<Integer,String> map) {
        if(map == null) {
            throw new ApiException("title_is_empty");
        }
        List<String> list = new ArrayList<>();
        map.forEach((k,v) -> {
            list.add(v);
        });
        Map<String,List<String>> wbTitle = new LinkedHashMap<>();
        wbTitle.put("序号",null);
        wbTitle.put("构建物/设备",null);
        wbTitle.put("巡检项目",null);
        wbTitle.put("巡检标准",null);
        wbTitle.put("巡检记录",list);
        return wbTitle;
    }




    public FileData exportDate(Map<String,Object> param) {

        String titile ="Excel合并导出标题";

        Map<Integer,String> map = new HashMap<>();
        map.put(1,"正常");
        map.put(2,"异常");
        map.put(3,"故障");
        List<Mock> list = mockData();
        List<List<String>> formatList = formatList(list);

        Map<String, List<String>> header = getHeader(map);

        AtomicInteger maxCol = new AtomicInteger();
        header.forEach((k,v) -> {
            if(CollectionUtils.isNotEmpty(v)) {
                maxCol.addAndGet(v.size());
            } else {
                maxCol.addAndGet(1);
            }
        });
        FileData fileData = new FileData() ;
        Row row;
        Cell cell;
        int rowNum = 0;
        // 需要合并的  开始行数后和结束行数
        int startMerge = 3;
        int endMerge = 2;
        boolean flag = true;
        String oldVl ="";
        try {
            XSSFWorkbook xb = new XSSFWorkbook();
            XSSFSheet sheet = xb.createSheet("新建sheet页");

            CellStyle cellStyle = ExcelTools.createCellContentStyle(xb);
            // 创建cell
            //前三行是标题表头合并行
            for (int i = 0; i < list.size() + 3; i++) {
                row = sheet.createRow(i);
                for (int j = 0; j < maxCol.intValue(); j++) {
                    cell = row.createCell(j);
                    cell.setCellStyle(cellStyle);
                }
            }
            //初始化标题表头
            initHeader(header, titile, xb, sheet, maxCol, rowNum);
            //正式内容填充
            for (int i = 0; i < formatList.size(); i++) {
                rowNum = 3 + i;
                row = sheet.getRow(rowNum);
                List<String> content = formatList.get(i);
                for (int j = 0; j < content.size(); j++) {
                    //确定需要合并的列好 如果是第1列
                    if(j == 0) {
                        if(flag) {
                            oldVl = content.get(j);
                            flag =false;
                        } else {
                            if(oldVl.equalsIgnoreCase(content.get(j))) {
                                endMerge++;
                            } else {
                                if(endMerge > startMerge){
                                    sheet.addMergedRegion(new CellRangeAddress(startMerge,endMerge,j, j));
                                    startMerge = rowNum;
                                    endMerge = startMerge;
                                    oldVl = content.get(j);
                                }
                            }
                        }
                    }
                    ExcelTools.createCell(row,cellStyle,j,content.get(j));
                }
            }
            if(endMerge > startMerge ){
                sheet.addMergedRegion(new CellRangeAddress(startMerge,endMerge,0 ,0));
            }
            //设置cell宽度
            for (int i = 0; i < maxCol.intValue() +1 ; i++) {
                sheet.setColumnWidth(i, 8 * 256 * 2);
            }
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            xb.write(os);
            os.flush();
            fileData.setBytes(os.toByteArray());
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return  fileData;


    }

    private void initHeader(Map<String,List<String>> header, String titile, XSSFWorkbook xb, XSSFSheet sheet, AtomicInteger maxCol, int rowNum) {
        CellStyle cellTitleStyle = ExcelTools.createCellTitleStyle(xb);
        Row row;
        //合并第一行
        sheet.addMergedRegion(new CellRangeAddress(0,0,0,maxCol.intValue() -1));
        row = sheet.getRow(rowNum);
        ExcelTools.createCell(row,cellTitleStyle,0,titile);
        rowNum ++;

        row = sheet.getRow(rowNum);
        CellStyle titleStyle = ExcelTools.createCellTitleStyle(xb);
        //需要跨列的格子
        Row row1 = sheet.getRow(rowNum +1);
        int index = 0;
        for (Map.Entry<String, List<String>> entry : header.entrySet()) {
            String key = entry.getKey();
            List<String> value = entry.getValue();
            if(CollectionUtils.isEmpty(value)) {
                sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum +1 , index ,index));
                ExcelTools.createCell(row,titleStyle,index,key);
                index++;
            } else {
                sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum ,index, index + value.size() -1));
                ExcelTools.createCell(row,titleStyle,index,key);
                for (int i = 0; i < value.size(); i++) {
                    ExcelTools.createCell(row1,cellTitleStyle,i,value.get(i));
                    index ++;
                }

            }
        }

    }


    public List<Mock> mockData () {
        List<Mock> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Mock mock = Mock.builder()
                    .name("张三")
                    .project(String.format("高新四路%d号",i))
                    .stand("标准规范" + i)
                    .record(Arrays.asList("xx,yy,zz,mm,nnn".split(",")))
                    .build();
            list.add(mock);
        }
        return list;
    }


    /**
     * 数据清洗   方便数据渲染
     * @param mocks
     * @return
     */
    private List<List<String>> formatList(List<Mock> mocks) {
        List<List<String>> list = new ArrayList<>();

        mocks.forEach(e -> {
            List<String> ls = new ArrayList<>();

            ls.add(e.getName());
            ls.add(e.getProject());
            ls.add(e.getStand());

            List<String> record = e.getRecord();
            if(CollectionUtils.isNotEmpty(record)) {
                record.forEach(v -> {
                    if(StringUtils.isEmpty(v)){
                        ls.add("-");
                    }else if (v.equalsIgnoreCase("xx")) {
                        ls.add("消息");
                    } else {
                        ls.add(v);
                    }
                });
            }
            list.add(ls);
        });
        return list;

    }



}


@Data
@Builder
class Mock {

    private String name;

    private String project;

    private String stand;

    private List<String> record;

}
